﻿#pragma once

#include <string>
#include "Parameter.h"

enum status_t {
	prog,
	def,
	func_def_begin,
	func_def_ret,
	AstCall_func
};

class AstNode;
class AstType;
class TupleType;
struct Temporary;

void packageName(char* name);
AstNode* createImport(char* name);
AstNode* appendImportName(AstNode* n, char* name);
void packageImport(AstNode* n);
void setPackageLines(Temporary* n);

AstType* getType( int type_id );
AstType* getClassType( char * name );
AstType* getFuncType();
AstType* makeArray(AstType* type, AstNode* list = nullptr);
AstNode* makeSequence(AstNode* list);

AstNode* makeEmpty();
AstNode* makeNull();

AstNode* let( const std::string& name, AstNode* value );

AstNode* unary(int op, AstNode* v);
AstNode* unaryAfter( int op, AstNode* v );
AstNode* binary( int op, AstNode* left, AstNode* right );
AstNode* binaryIs(AstNode* left, AstType* right);

// 定义
Parameter* defType(AstType* type, char* name = nullptr, AstNode* value = nullptr);

Temporary* createLines(AstNode* line);
Temporary* appendLines(Temporary* lines, AstNode* line);

Temporary* createLines(AstType* line);
Temporary* appendLines(Temporary* lines, AstType* line);

AstNode* createStringVector(char* s);
/// 添加一个列表项
AstNode* appendStringItem(AstNode* list, char* var);

AstNode* link(AstNode* left, AstNode* right);

AstNode* makeValue( const char* name, int32_t v );
AstNode* makeValue( const char* name, int64_t v );
AstNode* makeValue( const char* name, float v );
AstNode* makeValue( const char* name, double v );
AstNode* makeValue( const char* name, bool v );
AstNode* makeValue( const char* v );

AstNode* getVar( const char* name, bool right = true );
AstNode* makeIf(AstNode* cond, Temporary* block);
AstNode* setElse(AstNode* ifCond, Temporary* elseBlock);

AstNode* makeWhile( AstNode* cond, Temporary* block );
AstNode* makeFor(Parameter* let, AstNode* cond, AstNode* inc, Temporary* block );

AstNode* createFunction(int funcType, const std::string& name, Temporary*parameters,  Temporary* ret, Temporary* block );
AstNode* addFunctionBlock(AstNode*, Temporary* block);
AstNode* createOperator(int oper, Temporary*variables, Temporary* ret, Temporary* block);
AstType* createInterface( char* name, Temporary* block );
Temporary* setVariable(Temporary*, Parameter* block);

// 返回命令
AstNode* callReturn(AstNode* val=nullptr);

AstNode* makeSplice(AstNode* expr, AstNode* begin, AstNode* end);
AstNode* makeIndex(AstNode* expr, AstNode* index);

// 元组
AstNode* makeTuple(AstNode* elem, AstNode* second);
AstNode* tupleResolve(Temporary* type, AstNode* tuple);

AstNode * makeClass(int type, char * name, AstType * inherit, Temporary * block);
AstNode* makeConst(char* name, AstNode* value );

AstNode* createSwitch(AstNode* cond, Temporary* lines);
AstNode* createCase(Temporary* cond, Temporary* lines);

/////// try-catch //////////////
AstNode* makeCatch(Temporary* types, char* name, Temporary* lines);
AstNode* createTry(Temporary* block, Temporary* catchs, Temporary* finallyBlock );

/////////// GET, SET ///////////
AstNode* makeGet(char* name, Temporary* block);
AstNode* makeSet(char* name, AstType* type, char* value, Temporary* block);

AstNode* makeBased(AstNode* expr, Temporary* block);

AstNode * setProtected();

AstNode* makeInc(AstNode* expr, bool isInc = true);

AstNode* createEnum(char* name, Temporary* items);
AstNode* makeCall(char* name, Temporary* templateArgs, Temporary* args);
AstNode* makeDelete(AstNode* expr);
AstNode* createNew(AstType* type, char* name, Temporary* block);
AstNode* createDef(Parameter* def);
AstNode* appendDef(AstNode* def, char* name, AstNode* value = nullptr);

Parameter* makeParam(char* name, AstType* type= nullptr);
Parameter* makeParam(AstNode* node);

Temporary* createVector(Parameter* param);
Temporary* appendItem(Temporary* vec, Parameter* param);